package gov.pbc.nn.kjgl.task.view;

import java.io.File;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.model.DefaultDept;
import com.bstek.bdf2.core.model.DefaultUser;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.data.variant.Record;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.designer.utils.EscapeUtils;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.bdf.service.DeptService;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.entity.BaseEntity;
import gov.pbc.nn.core.utils.GetTableUtils;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.task.dao.TaskDao;
import gov.pbc.nn.kjgl.task.entity.TaskBranchUser;
import gov.pbc.nn.kjgl.task.entity.TaskEntity;
import gov.pbc.nn.kjgl.task.entity.TaskHandleFile;
import gov.pbc.nn.kjgl.task.entity.TaskProcessor;
import gov.pbc.nn.kjgl.task.entity.TaskResultFile;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

@Component
public class TaskPR {

	@Autowired
	private TaskDao taskDao;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;

	@Resource(name = ProcessClient.BEAN_ID)
	private ProcessClient pc;

	@Resource(name = TaskClient.BEAN_ID)
	private TaskClient tc;

	@Autowired
	private DeptService deptService;

	@DataProvider
	public TaskEntity loadTask(String id) throws Exception {
		if (StringUtils.isEmpty(id)) {
			return null;
		}
		TaskEntity taskEntity = (TaskEntity) this.taskDao.get(id, TaskEntity.class);
		return taskEntity;
	}

	@DataProvider
	public void loadTasks(String taskType, Page<TaskEntity> page, Criteria criteria) throws Exception {
		DetachedCriteria dc = this.taskDao.buildDetachedCriteria(criteria, TaskEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("taskType", taskType));
		if (taskType.equals("ZZ")) {
			dc.add(Restrictions.eq("deptId",ContextHolder.getLoginUser().getDepts().get(0).getId()));
		}
		if (!this.taskDao.containsProperty("state", criteria)) {
			dc.add(Restrictions.in("state", new Object[] { 0, 10 }));
		}

		dc.addOrder(Order.asc("state"));
		this.taskDao.pagingQuery(page, dc);
	}

	@DataProvider
	public Collection<TaskBranchUser> getBranchUsersbyTaskId(String TaskEntityId) throws Exception {
		return this.taskDao.getBranchUsersbyTaskId(TaskEntityId);
	}

	@DataProvider
	public Collection<TaskProcessor> getProcessorsbyTaskId(String TaskEntityId) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskEntityId", TaskEntityId);
		return this.taskDao.query(
				" from " + TaskProcessor.class.getName() + " where taskEntityId=:taskEntityId and invalid=false ", map);
	}

	@DataProvider
	public Collection<TaskHandleFile> getHandleFilesbyTaskId(String TaskEntityId) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskEntityId", TaskEntityId);
		return this.taskDao.query(
				" from " + TaskHandleFile.class.getName() + " where taskEntityId=:taskEntityId and invalid=false ",
				map);
	}

	@DataProvider
	public Collection<TaskResultFile> getResultFilesbyTaskId(String TaskEntityId) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskEntityId", TaskEntityId);
		return this.taskDao.query(
				" from " + TaskResultFile.class.getName() + " where taskEntityId=:taskEntityId and invalid=false ",
				map);
	}

	@DataProvider
	public Collection<Opinion> getOpinions(String taskEntityId) throws Exception {
		return UfloUtils.getOpinions(null, taskEntityId, null, null, null);
	}

	@DataProvider
	public Collection<IUser> getCzs() throws Exception {
		return SecurityUtils.getUserByRoleForDept(
				((Dept) ContextHolder.getLoginUser().getDepts().get(0)).getCDept().getId(), Constants.ROLE_CZ);
	}

	@SuppressWarnings("unchecked")
	@DataProvider
	public TaskEntity getAddProcessorTask(Map<String, Object> param) throws Exception {
		String taskEntityId = (String) param.get("businessId");
		TaskEntity taskEntity = this.loadTask(taskEntityId);
		TaskEntity enity = EntityUtils.toEntity(taskEntity);
		String taskId = (String) param.get("taskId");
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		Map<String, Object> branch = (Map<String, Object>) this.pc.getProcessVariable("branch",
				task.getProcessInstanceId());
		EntityUtils.setValue(enity, "BranchUser",
				this.taskDao.get(branch.get("branchId").toString(), TaskBranchUser.class));
		return enity;
	}

	@SuppressWarnings("unchecked")
	@DataProvider
	public TaskEntity getProcessorDoTask(Map<String, Object> param) throws Exception {
		String taskEntityId = (String) param.get("businessId");
		TaskEntity taskEntity = this.loadTask(taskEntityId);
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		String taskId = (String) param.get("taskId");
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		Map<String, Object> map = new HashMap<String, Object>();
		if (taskEntity.getNeedBranch() == true) {
			Map<String, Object> branch = (Map<String, Object>) this.pc.getProcessVariable("branch",
					task.getProcessInstanceId());
			map.put("taskEntityId", branch.get("branchId"));
		} else {
			map.put("taskEntityId", taskEntityId);
		}
		map.put("processorname", ContextHolder.getLoginUserName());
		List<TaskProcessor> processors = this.taskDao.query("from " + TaskProcessor.class.getName()
				+ " where taskEntityId=:taskEntityId and username=:processorname and invalid=false", map);
		if (processors != null && processors.size() > 0)
			EntityUtils.setValue(entity, "Processor", processors.get(0));
		return entity;
	}

	@SuppressWarnings("unchecked")
	@DataProvider
	public TaskEntity getBranchSHTaskEntity(Map<String, Object> param) throws Exception {
		String taskEntityId = (String) param.get("businessId");
		String taskId = (String) param.get("taskId");
		TaskEntity taskEntity = this.loadTask(taskEntityId);
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		Map<String, Object> branch = (Map<String, Object>) this.pc.getProcessVariable("branch",
				task.getProcessInstanceId());
		TaskBranchUser branchUser = this.taskDao.get(branch.get("branchId").toString(), TaskBranchUser.class);
		final TaskBranchUser branchUserEntity = EntityUtils.toEntity(branchUser);
		final Object ProcessorObject = this.pc.getProcessVariable("modifyProcessorList", task.getProcessInstanceId());
		Collection<TaskProcessor> processors = this.taskDao
				.doInHibernateSession(new ISessionCallback<Collection<TaskProcessor>>() {
					@Override
					public Collection<TaskProcessor> doInSession(org.hibernate.Session session) {
						String sql = " from " + TaskProcessor.class.getName()
								+ " where taskEntityId=:taskEntityId and invalid=false ";
						if (ProcessorObject != null && ((List<String>) ProcessorObject).size() > 0) {
							sql += " and username in (:usernames) ";
						}
						Query query = session.createQuery(sql);
						query.setString("taskEntityId", branchUserEntity.getId());
						if (ProcessorObject != null && ((List<String>) ProcessorObject).size() > 0) {
							query.setParameterList("usernames", (List<String>) ProcessorObject);
						}
						return query.list();
					}
				});
		EntityUtils.setValue(branchUserEntity, "Processors", processors);
		EntityUtils.setValue(entity, "BranchUser", branchUserEntity);

		return entity;
	}

	@Transactional
	@DataResolver
	private void deleteBranchUserByTaskId(final String taskEntityId) throws Exception {
		this.taskDao.doInHibernateSession(new ISessionCallback<Integer>() {
			@Override
			public Integer doInSession(org.hibernate.Session session) {
				Query query = session.createQuery("update " + TaskBranchUser.class.getName()
						+ " set invalid=true where  taskEntityId=:taskEntityId");
				query.setString("taskEntityId", taskEntityId);
				return query.executeUpdate();
			}
		});
	}

	@SuppressWarnings("unchecked")
	@DataProvider
	public TaskEntity getPromoterSHTaskEntity(Map<String, Object> param) throws Exception {
		String taskEntityId = (String) param.get("businessId");
		String taskId = (String) param.get("taskId");
		final TaskEntity taskEntity = this.loadTask(taskEntityId);
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		if (taskEntity.getNeedBranch() == true) {
			final Object BranchUserObject = this.pc.getProcessVariable("modifyBranchUserList",
					task.getProcessInstanceId());
			List<TaskBranchUser> branchUsers = this.taskDao
					.doInHibernateSession(new ISessionCallback<List<TaskBranchUser>>() {
						@Override
						public List<TaskBranchUser> doInSession(org.hibernate.Session session) {
							String sql = " from " + TaskBranchUser.class.getName()
									+ " where taskEntityId=:taskEntityId and invalid=false ";
							if (BranchUserObject != null && ((List<String>) BranchUserObject).size() > 0) {
								sql += " and username in (:usernames) ";
							}
							Query query = session.createQuery(sql);
							query.setString("taskEntityId", taskEntity.getId());
							if (BranchUserObject != null && ((List<String>) BranchUserObject).size() > 0) {
								query.setParameterList("usernames", (List<String>) BranchUserObject);
							}
							return query.list();
						}
					});

			EntityUtils.setValue(entity, "BranchUsers", branchUsers);
		} else {
			final Object ProcessorObject = this.pc.getProcessVariable("modifyProcessorList",
					task.getProcessInstanceId());
			List<TaskProcessor> processors = this.taskDao
					.doInHibernateSession(new ISessionCallback<List<TaskProcessor>>() {
						@Override
						public List<TaskProcessor> doInSession(org.hibernate.Session session) {
							String sql = " from " + TaskProcessor.class.getName()
									+ " where taskEntityId=:taskEntityId and invalid=false ";
							if (ProcessorObject != null && ((List<String>) ProcessorObject).size() > 0) {
								sql += " and username in (:usernames) ";
							}
							Query query = session.createQuery(sql);
							query.setString("taskEntityId", taskEntity.getId());
							if (ProcessorObject != null && ((List<String>) ProcessorObject).size() > 0) {
								query.setParameterList("usernames", (List<String>) ProcessorObject);
							}
							return query.list();
						}
					});

			EntityUtils.setValue(entity, "Processors", processors);
		}
		return entity;
	}

	@Transactional
	@DataResolver
	private void deleteProcessorByTaskId(final String taskEntityId) throws Exception {
		this.taskDao.doInHibernateSession(new ISessionCallback<Integer>() {
			@Override
			public Integer doInSession(org.hibernate.Session session) {
				Query query = session.createQuery("update " + TaskProcessor.class.getName()
						+ " set invalid=true where taskEntityId=:taskEntityId");
				query.setString("taskEntityId", taskEntityId);
				return query.executeUpdate();
			}
		});
	}

	@Transactional
	@DataResolver
	private void saveEntity(BaseEntity entity) throws Exception {
		EntityState state = EntityUtils.getState(entity);
		if (state.equals(EntityState.NEW)) {
			if (entity instanceof TaskEntity) {
				TaskEntity te = (TaskEntity) entity;
				Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
				te.setDeptId(dept.getCDept().getId());
				te.setDeptName(dept.getCDept().getName());
				te.setState(0);
			}
			this.taskDao.save(entity);
		} else if (state.equals(EntityState.MODIFIED)) {
			this.taskDao.update(entity);
		} else if (state.equals(EntityState.DELETED)) {
			this.taskDao.delete(entity);
		}
	}

	private <T> void saveSubEntitys(List<T> entitys, String taskEntityId) throws Exception {
		if (entitys == null || entitys.size() <= 0)
			return;
		Method method = entitys.get(0).getClass().getDeclaredMethod("setTaskEntityId", new Class[] { String.class });
		for (T entity : entitys) {
			method.invoke(entity, new Object[] { taskEntityId });
			this.saveEntity((BaseEntity) entity);
		}
	}

	@Transactional
	@DataResolver
	public void updateTask(TaskEntity taskEntity) throws Exception {
		TaskEntity task = EntityUtils.toEntity(taskEntity);
		this.saveEntity(task);
		List<TaskBranchUser> BranchUsers = EntityUtils.getValue(task, "BranchUsers");
		List<TaskProcessor> Processors = EntityUtils.getValue(task, "Processors");
		List<TaskHandleFile> HandleFiles = EntityUtils.getValue(task, "HandleFiles");
		// System.out.println(taskEntity.get);
		if (taskEntity.getNeedBranch()) {
			this.saveSubEntitys(BranchUsers, taskEntity.getId());
			this.deleteProcessorByTaskId(taskEntity.getId());
		} else if (taskEntity.getDriectProcessor()) {
			this.saveSubEntitys(Processors, taskEntity.getId());
			this.deleteBranchUserByTaskId(taskEntity.getId());
		}

		this.saveSubEntitys(HandleFiles, taskEntity.getId());
	}

	@Transactional
	@DataResolver
	public void updateAddProcessorTask(TaskEntity taskEntity) throws Exception {
		TaskEntity task = EntityUtils.toEntity(taskEntity);
		TaskBranchUser BranchUser = EntityUtils.getValue(task, "BranchUser");
		List<TaskProcessor> Processors = EntityUtils.getValue(BranchUser, "Processors");
		this.saveSubEntitys(Processors, BranchUser.getId());
	}

	@Transactional
	@DataResolver
	public void updateProcessorDoTask(TaskEntity taskEntity) throws Exception {
		TaskEntity task = EntityUtils.toEntity(taskEntity);
		TaskProcessor processor = EntityUtils.getValue(task, "Processor");
		List<TaskResultFile> resultFiles = EntityUtils.getValue(processor, "ResultFiles");
		this.taskDao.update(processor);
		this.saveSubEntitys(resultFiles, processor.getId());
	}

	@Transactional
	@DataResolver
	@Expose
	public void deleteTask(TaskEntity taskEntity) throws Exception {
		this.taskDao.delete(taskEntity);
		UfloUtils.deleteProcessInstance(taskEntity.getId(),true);
	}

	@Expose
	@Transactional
	public void takeBack(String businessId) {
		TaskEntity task = this.taskDao.get(businessId, TaskEntity.class);
		if (task.getState() != 10) {
			throw new UnsupportedOperationException("只有处于审核中的业务流程才可以收回！");
		}
		task.setState(0);
		this.taskDao.update(task);
		UfloUtils.deleteProcessInstance(businessId,true);
	}

	@Expose
	@Transactional
	public void forceComplete(String businessId) {
		TaskEntity task = this.taskDao.get(businessId, TaskEntity.class);
		task.setState(30);
		this.taskDao.update(task);
		UfloUtils.deleteProcessInstance(businessId,false);
	}

	@Expose
	public String hasBranch(List<Record> depts) throws Exception {
		for (Record dept : depts) {
			if (dept.getString("id").startsWith(Dept.NANNING) == true) {
				return "【"+dept.getString("name") + "】属于南宁中支,请重新选择!";
			} else if (StringUtils.isNotBlank(dept.getString("deptLevel"))) {
				return "【"+dept.getString("name") + "】不属于部门,请重新选择!";
			} else {
				List<IUser> users = SecurityUtils.getUserByRoleForDept(dept.getString("id"),
						Constants.ROLE_TASK_FENBAN);
				if (users.size() <= 0)
					return "【"+dept.getString("name") + "】未设置【"+Constants.ROLE_TASK_FENBAN+"】角色，无法处理该任务!";

			}
		}
		return null;
	}

	@FileResolver
	@DataResolver
	public Map<String, String> process1(UploadFile file, Map<String, Object> parameter) throws Exception {
		// String param1 = (String) parameter.get("param1");//
		// 获取UploadAction的parameter对应的参数值
		// String param2 = (String) parameter.get("param2");//
		// 获取UploadAction的parameter对应的参数值
		// Integer id= (Integer)parameter.get("id");

		// String fileId = (String)parameter.get("fileId");
		String filename = file.getFileName();
		String filesavename = UUID.randomUUID().toString();
		Path path = Paths.get(Configure.getString("TASK_FILE_UPLOAD_PATH"), "/HandleFile");
		Files.createDirectories(path);
		path = path.resolve(filesavename);
		File destFile = Files.createFile(path).toFile();
		file.transferTo(destFile);
		Map<String, String> data = new HashMap<String, String>();
		data.put("fileName", filename);
		data.put("path", destFile.getAbsolutePath());
		// data.put("fileId", fileId);
		return data;
	}

	@FileResolver
	@DataResolver
	public Map<String, String> processResult(UploadFile file, Map<String, Object> parameter) throws Exception {
		String filename = file.getFileName();
		String filesavename = UUID.randomUUID().toString();
		Path path = Paths.get(Configure.getString("TASK_FILE_UPLOAD_PATH"), "/ResultFile");
		Files.createDirectories(path);
		path = path.resolve(filesavename);
		File destFile = Files.createFile(path).toFile();
		file.transferTo(destFile);
		Map<String, String> data = new HashMap<String, String>();
		data.put("fileName", filename);
		data.put("path", destFile.getAbsolutePath());
		// data.put("fileId", fileId);
		return data;
	}

	@FileProvider
	public DownloadFile download(Map<String, Object> parameter) throws Exception {
		String fileName = EscapeUtils.unescape((String) parameter.get("fileName"));
		String path = EscapeUtils.unescape((String) parameter.get("path"));
		DownloadFile df = new DownloadFile(new File(path));// 返回一个文件对象就可以
		df.setFileName(fileName);
		df.setName(fileName);
		return df;
	}

	private void completeTask(String taskEntityId, String taskId, String opinion, Map<String, Object> variables) {
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		if (variables != null)
			this.pc.saveProcessVariables(task.getProcessInstanceId(), variables);
		final Opinion o = new Opinion();
		o.setBusKey(taskEntityId);
		o.setBusTable(GetTableUtils.getTablename(TaskEntity.class));
		o.setOpinion(opinion);
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName("任务管理");
		o.setTaskId(ltaskId);
		o.setTaskName(task.getTaskName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);
		this.tc.start(ltaskId);
		this.tc.complete(ltaskId);
	}

	@Expose
	@Transactional
	public void startProcess(Map<String, Object> params) throws Exception {
		String taskEntityId = (String) params.get("taskEntityId");
		String taskId = (String) params.get("taskId");
		String taskType = (String) params.get("taskType");
		boolean driectProcessor = (boolean) params.get("driectProcessor");
		TaskEntity te = this.taskDao.get(taskEntityId, TaskEntity.class);
		te.setState(10);
		this.taskDao.update(te);

		if (StringUtils.isNotEmpty(taskId)) {
			this.completeTask(taskEntityId, taskId, "修改后重新提交申请", params);
		} else {
			if (driectProcessor == true) {
				Collection<TaskProcessor> processors = this.getProcessorsbyTaskId(taskEntityId);
				List<String> processorList = new ArrayList<String>();
				for (TaskProcessor processor : processors) {
					processorList.add(processor.getUsername());
				}
				params.put("processorList", processorList);
			}
			StartProcessInfo spi = new StartProcessInfo();
			spi.setBusinessId(taskEntityId);
			spi.setPromoter(ContextHolder.getLoginUserName());
			spi.setCompleteStartTask(true);
			params.put("taskEntityName", te.getName());
			spi.setVariables(params);
			ProcessInstance pi = null;
			if (taskType.equals("NN"))
				pi = this.pc.startProcessByName("任务管理", spi);
			else if (taskType.equals("ZZ"))
				pi = this.pc.startProcessByName("地市任务管理", spi);
			if (pi != null) {
				final Opinion o = new Opinion();
				o.setBusKey(taskEntityId);
				o.setBusTable(GetTableUtils.getTablename(TaskEntity.class));
				o.setOpinion("提交申请");
				o.setProcessInstanceId(pi.getId());
				o.setProcessName("任务管理");
				o.setTaskName("申请任务");
				o.setUsername(ContextHolder.getLoginUserName());
				o.setCname(ContextHolder.getLoginUser().getCname());
				o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
				o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
				this.coreHibernateDao.save(o);
			}
		}
	}

	@Expose
	public void cancelApply(Map<String, Object> params) throws Exception {
		String taskEntityId = (String) params.get("taskEntityId");
		String taskId = (String) params.get("taskId");
		String opinion = (String) params.get("opinion");
		long ltaskId = Long.parseLong(taskId);

		TaskEntity te = this.taskDao.get(taskEntityId, TaskEntity.class);
		te.setState(20);
		this.taskDao.update(te);

		Task task = this.tc.getTask(ltaskId);
		final Opinion o = new Opinion();
		o.setBusKey(taskEntityId);
		o.setBusTable(GetTableUtils.getTablename(TaskEntity.class));
		o.setOpinion("申请人撤销申请:" + opinion);
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName("任务管理");
		o.setTaskId(ltaskId);
		o.setTaskName(task.getTaskName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("processResult", opinion);
		this.tc.forward(ltaskId, "结束", variables);
	}

	@Expose
	@Transactional
	public void CZSH(Map<String, Object> params) throws Exception {
		String taskEntityId = (String) params.get("taskEntityId");
		String taskId = (String) params.get("taskId");
		String opinion = (String) params.get("opinion");
		Integer agree = (Integer) params.get("agree");
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		if (agree == 0) {
			this.completeTask(taskEntityId, taskId, opinion, params);
		} else if (agree == 2) {
			final Opinion o = new Opinion();
			o.setBusKey(taskEntityId);
			o.setBusTable(GetTableUtils.getTablename(TaskEntity.class));
			o.setOpinion(opinion);
			o.setProcessInstanceId(task.getProcessInstanceId());
			o.setProcessName("任务管理");
			o.setTaskId(ltaskId);
			o.setTaskName(task.getTaskName());
			o.setUsername(ContextHolder.getLoginUserName());
			o.setCname(ContextHolder.getLoginUser().getCname());
			o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
			o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
			this.coreHibernateDao.save(o);
			this.tc.forward(ltaskId, task.getNodeName(), params);
		} else if (agree == 1) {
			boolean driectProcessor = (boolean) params.get("driectProcessor");
			if (driectProcessor == true) {
				Collection<TaskProcessor> processors = this.getProcessorsbyTaskId(taskEntityId);
				List<String> processorList = new ArrayList<String>();
				for (TaskProcessor processor : processors) {
					processorList.add(processor.getUsername());
				}
				params.put("processorList", processorList);
			}
			this.completeTask(taskEntityId, taskId, opinion, params);
		}
	}

	@Expose
	@Transactional
	public void CZSHZZ(TaskEntity taskEntity) throws Exception {
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		String taskId = EntityUtils.getValue(entity, "taskId");
		boolean isagree = EntityUtils.getValue(entity, "isagree");
		boolean reCollectOpinion = EntityUtils.getValue(entity, "reCollectOpinion");
		String opinion = EntityUtils.getValue(entity, "opinion");
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("agree", isagree);
		variables.put("reCollectOpinion", reCollectOpinion);
		this.completeTask(taskEntity.getId(), taskId, opinion, variables);
	}

	@Expose
	@Transactional
	public void AddProcessor(TaskEntity taskEntity) throws Exception {
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		TaskBranchUser branchUser = EntityUtils.getValue(entity, "BranchUser");
		List<TaskProcessor> processors = EntityUtils.getValue(branchUser, "Processors");
		String taskId = EntityUtils.getValue(entity, "taskId");
		List<String> processorList = new ArrayList<String>();
		String cnamestr = "";
		if (processors != null) {
			for (TaskProcessor taskProcessor : processors) {
				processorList.add(taskProcessor.getUsername());
				cnamestr += taskProcessor.getCname() + ",";
			}
		}
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("processorList", processorList);
		variables.put("modifyProcessorList", new ArrayList<String>());
		variables.put("needBranch", true);
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		Map<String, Object> branch = (Map<String, Object>) this.pc.getProcessVariable("branch",
				task.getProcessInstanceId());
		branch.put("username", ContextHolder.getLoginUserName());
		variables.put("branch", branch);
		this.completeTask(taskEntity.getId(), taskId, "添加处理人:" + cnamestr, variables);
	}

	@Expose
	@Transactional
	public void ProcessorDo(TaskEntity taskEntity) throws Exception {
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		TaskProcessor processor = EntityUtils.getValue(entity, "Processor");
		String taskId = EntityUtils.getValue(entity, "taskId");
		List<TaskResultFile> resultFiles = EntityUtils.getValue(processor, "ResultFiles");
		this.saveSubEntitys(resultFiles, processor.getId());
		this.completeTask(taskEntity.getId(), taskId, processor.getRemark(), null);
	}

	@Expose
	@Transactional
	public void BranchSH(TaskEntity taskEntity) throws Exception {
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		String opinion = EntityUtils.getValue(entity, "opinion");
		TaskBranchUser branchUser = EntityUtils.getValue(entity, "BranchUser");
		List<TaskProcessor> processors = EntityUtils.getValue(branchUser, "Processors");
		String taskId = EntityUtils.getValue(entity, "taskId");
		List<String> modifyProcessorList = new ArrayList<String>();
		for (TaskProcessor taskProcessor : processors) {
			boolean isagree = EntityUtils.getValue(taskProcessor, "isagree");
			if (isagree == false) {
				modifyProcessorList.add(taskProcessor.getUsername());
			}
		}
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("modifyProcessorList", modifyProcessorList);
		if (modifyProcessorList.size() <= 0) {
			variables.put("agree", true);
		} else {
			variables.put("agree", false);
		}
		this.completeTask(taskEntity.getId(), taskId, opinion, variables);
	}

	@Expose
	@Transactional
	public void PromoterSH(TaskEntity taskEntity) throws Exception {
		TaskEntity entity = EntityUtils.toEntity(taskEntity);
		String taskId = EntityUtils.getValue(entity, "taskId");
		String opinion = EntityUtils.getValue(entity, "opinion");
		Map<String, Object> variables = new HashMap<String, Object>();
		if (taskEntity.getNeedBranch() == false) {
			List<TaskProcessor> processors = EntityUtils.getValue(entity, "Processors");
			List<String> modifyProcessorList = new ArrayList<String>();
			for (TaskProcessor taskProcessor : processors) {
				boolean isagree = EntityUtils.getValue(taskProcessor, "isagree");
				if (isagree == false) {
					modifyProcessorList.add(taskProcessor.getUsername());
				}
			}
			variables.put("modifyProcessorList", modifyProcessorList);
			if (modifyProcessorList.size() <= 0) {
				variables.put("agree", true);
			} else {
				variables.put("agree", false);
			}
		} else {
			List<TaskBranchUser> branchUsers = EntityUtils.getValue(entity, "BranchUsers");
			List<String> modifyBranchUserList = new ArrayList<String>();
			for (TaskBranchUser taskBranchUser : branchUsers) {
				boolean isagree = EntityUtils.getValue(taskBranchUser, "isagree");
				if (isagree == false) {
					modifyBranchUserList.add(taskBranchUser.getUsername());
				}
			}
			variables.put("modifyBranchUserList", modifyBranchUserList);
			if (modifyBranchUserList.size() <= 0) {
				variables.put("agree", true);
			} else {
				variables.put("agree", false);
			}
		}
		this.completeTask(taskEntity.getId(), taskId, opinion, variables);
	}

	@DataProvider
	public String getFbrDeptByFbrUsername(String username) {
		if (StringUtils.isEmpty(username)) {
			return null;
		}
		List<IDept> ls = deptService.loadUserDepts(username);
		IDept d = ls.get(0);
		return d.getName();
	}
}
